
// Copyright (C) 2009 Luca Piccioni
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;

namespace Derm.BindGen
{
	/// <summary>
	/// Partial classes factory.
	/// </summary>
	abstract class PartialClassFactory
	{
		[Flags]
		public enum SourceExt
		{
			None =		0x00,
			ARB =		0x01,
			EXT =		0x02,
			ATI =		0x04,
			NV =		0x08,
			OTHERS =	0x10,
			All =		0x1F
		}

		public PartialClassFactory(string ns, string cName)
		{
			Debug.Assert(ns != null);
			Debug.Assert(cName != null);

			mNamespace = ns;
			mClassName = cName;
			
		}

		public string ClassName
		{
			get { return (mClassName); }
		}

		public string Namespace
		{
			get { return (null); }
		}
		
		/// <summary>
		/// Class namespace.
		/// </summary>
		private string mNamespace = null;
		/// <summary>
		/// Class name.
		/// </summary>
		private string mClassName = null;
		
		public virtual void WriteAssembly(string path, SourceExt exts)
		{
			WriteAssemblyImplementation(path, null);
		}

		protected delegate void WriteImplementation(StreamWriter sw);

		protected virtual void WriteAssemblyImplementation(string path, WriteImplementation impl)
		{
			StreamWriter sw = new StreamWriter(path);
			
			sw.WriteLine();
			// Licence
			sw.WriteLine("// Copyright (C) 2009-2011 Luca Piccioni");
			sw.WriteLine("//");
			sw.WriteLine("// This program is free software: you can redistribute it and/or modify");
			sw.WriteLine("// it under the terms of the GNU General Public License as published by");
			sw.WriteLine("// the Free Software Foundation, either version 3 of the License, or");
			sw.WriteLine("// (at your option) any later version.");
			sw.WriteLine("//");
			sw.WriteLine("// This program is distributed in the hope that it will be useful,");
			sw.WriteLine("// but WITHOUT ANY WARRANTY; without even the implied warranty of");
			sw.WriteLine("// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the");
			sw.WriteLine("// GNU General Public License for more details.");
			sw.WriteLine("//");
			sw.WriteLine("// You should have received a copy of the GNU General Public License");
			sw.WriteLine("// along with this program.  If not, see <http://www.gnu.org/licenses/>.");
			sw.WriteLine();
			sw.WriteLine("using System;");
			sw.WriteLine("using System.Collections.Generic;");
			sw.WriteLine("using System.Diagnostics;");
			sw.WriteLine("using System.IO;");
			sw.WriteLine("using System.Reflection;");
			sw.WriteLine("using System.Runtime.InteropServices;");
			sw.WriteLine("using System.Text;");
			sw.WriteLine();

			sw.WriteLine("#pragma warning disable 1572, 1573");
			sw.WriteLine();

			// Namespace
			sw.WriteLine("namespace "+mNamespace+" {");
			sw.WriteLine();
			// Outer class
			sw.WriteLine("	/// <summary>");
			sw.WriteLine("	/// Implementation of the OpenGL specification ");
			sw.WriteLine("	/// </summary>");
			sw.WriteLine("	public unsafe partial class "+mClassName+" : ProcLoader");
			sw.WriteLine("	{");
			sw.WriteLine();
			
			// Write implementation
			if (impl != null)
				impl(sw);

			// Outer class close
			sw.WriteLine("	}");
			// Namespace close
			sw.WriteLine("}");
			
			sw.Close();
		}
		
		/// <summary>
		/// Delegate nested class.
		/// </summary>
		public static readonly string PATH_DELEGATE = "Delegate";
		/// <summary>
		/// Import nested class.
		/// </summary>
		public static readonly string PATH_IMPORT = "Import";
		/// <summary>
		/// C# binding class implementation (routine specific).
		/// </summary>
		public static readonly string PATH_BINDING = "Binding";
		/// <summary>
		/// C# binding class implementation (enum specific)
		/// </summary>
		public static readonly string CLASS_ENUM = "Enums";
	}
}
